package com.sdy.sd;

import android.annotation.SuppressLint;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;

import java.util.Timer;
import java.util.TimerTask;

/**
 * An example full-screen activity that shows and hides the system UI (i.e.
 * status bar and navigation/system bar) with user interaction.
 */
public class FullscreenActivity extends AppCompatActivity implements View.OnClickListener {
    /**
     * Whether or not the system UI should be auto-hidden after
     * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
     */
    private static final boolean AUTO_HIDE = true;

    /**
     * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
     * user interaction before hiding the system UI.
     */
    private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
    private static String TAG = "MainActivity";

    /**
     * Some older devices needs a small delay between UI widget updates
     * and a change of the status and navigation bar.
     */
    private static final int UI_ANIMATION_DELAY = 300;
    private final Handler mHideHandler = new Handler();
    private SdView mRegionMain = null;
    private SdGame mSdGame = null;
    Button mBtnNewGame = null;
    Button mBtnAnswer = null;
    Button mBtnCheck = null;
    Button mBtnExit = null;
    Button mBtnLevelSet = null;
    Button mBtnHint = null;
    Button mBtnHanabParti = null;
    Button mBtnHanabBmps = null;
    Button mBtnWinAni = null;
    Button mBtnArtPix = null;
    SdHint mViewHint = null;
    AniFirework mFirework = null;
    int mTmpDiffiLevel = 0;
    ParticleFW mPartiFwView = null;
    static public DisplayMetrics mDm; //new DisplayMetrics()
    Timer mTm = null;
    TimerTask mTask = null;
    int mMoreRedrawCnt = 0;
    public static final int REDRAW_MAX = 50;

    private final Runnable mHidePart2Runnable = new Runnable() {
        @SuppressLint("InlinedApi")
        @Override
        public void run() {
            // Delayed removal of status and navigation bar

            // Note that some of these constants are new as of API 16 (Jelly Bean)
            // and API 19 (KitKat). It is safe to use them, as they are inlined
            // at compile-time and do nothing on earlier devices.
            mRegionMain.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        }
    };
    private View mControlsView;
    private final Runnable mShowPart2Runnable = new Runnable() {
        @Override
        public void run() {
            // Delayed display of UI elements
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.show();
            }
            mControlsView.setVisibility(View.VISIBLE);
        }
    };
    private boolean mVisible;
    private final Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            hide();
        }
    };
    /**
     * Touch listener to use for in-layout UI controls to delay hiding the
     * system UI. This is to prevent the jarring behavior of controls going away
     * while interacting with activity UI.
     */
    private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (AUTO_HIDE) {
                        delayedHide(AUTO_HIDE_DELAY_MILLIS);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    view.performClick();
                    break;
                default:
                    break;
            }
            return false;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mDm = getResources().getDisplayMetrics();
        long ml = System.currentTimeMillis();
        setContentView(R.layout.activity_fullscreen);
        FrameLayout top1 = (FrameLayout) findViewById(R.id.most_top_lo);
        top1.setBackgroundColor(Color.BLACK);
        Log.e(TAG, "setContentView use:" + (System.currentTimeMillis() - ml) + "ms");

        mVisible = true;
        mControlsView = findViewById(R.id.fullscreen_content_controls);
        mRegionMain = findViewById(R.id.fullscreen_content);
        assert(mRegionMain instanceof SdView);
        mSdGame = new SdGame(this);
        mRegionMain.mGame = mSdGame;

        mViewHint = (SdHint)findViewById(R.id.hint);
        mSdGame.mHint = mViewHint;

        mBtnNewGame = (Button)findViewById(R.id.new_game);
        mBtnAnswer = (Button)findViewById(R.id.condi_answer);
        mBtnCheck = (Button)findViewById(R.id.check_err);
        mBtnExit = (Button)findViewById(R.id.btn_quit);
        mBtnLevelSet = (Button)findViewById(R.id.btn_diff_level);
        mBtnHint = (Button)findViewById(R.id.btn_hint);
        mBtnHanabParti = (Button)findViewById(R.id.btn_hanab_parti);
        mBtnHanabBmps = (Button)findViewById(R.id.btn_hanab_bmps);
        mBtnWinAni = (Button)findViewById(R.id.btn_win_ani);
        mBtnArtPix = (Button)findViewById(R.id.btn_art_pix);
        mFirework = (AniFirework) findViewById(R.id.iv_fireworks);
        mPartiFwView = (ParticleFW)findViewById(R.id.iv_particle_fw);

        // Set up the user interaction to manually show or hide the system UI.
        mRegionMain.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                toggle();
            }
        });
        // Upon interacting with UI controls, delay any scheduled hide()
        // operations to prevent the jarring behavior of controls going away
        // while interacting with the UI.
        findViewById(R.id.dummy_button).setOnTouchListener(mDelayHideTouchListener);
        mBtnNewGame.setOnClickListener(this);
        mBtnAnswer.setOnClickListener(this);
        mBtnCheck.setOnClickListener(this);
        mBtnExit.setOnClickListener(this);
        mBtnLevelSet.setOnClickListener(this);
        mBtnHint.setOnClickListener(this);
        mBtnHanabParti.setOnClickListener(this);
        mBtnHanabBmps.setOnClickListener(this);
        mBtnWinAni.setOnClickListener(this);
        mBtnArtPix.setOnClickListener(this);

        mBtnNewGame.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
        mBtnAnswer.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
        mBtnCheck.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
        mBtnExit.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
        mBtnLevelSet.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
        mBtnHint.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));

        mBtnAnswer.setEnabled(false);
        mBtnCheck.setEnabled(false);
        if(0 != mSdGame.mGameLevel) { //hide if not test level
            mBtnHanabParti.setVisibility(View.GONE);
            mBtnHanabBmps.setVisibility(View.GONE);
            mBtnWinAni.setVisibility(View.GONE);
            mBtnArtPix.setVisibility(View.GONE);
        }
        Log.e(TAG, mDm.toString());

        LocalBroadcastManager lb = LocalBroadcastManager.getInstance(this);
        IntentFilter itf = new IntentFilter();
        itf.addAction("reqReset");
        itf.addAction("reqNewGame");
        itf.addAction("notifyWin");
        itf.addAction("notifyEnterGaming");

        BroadcastReceiver r = new BroadcastReceiver() {public void onReceive(Context context, Intent intent) {
            String s = intent.getAction();
            if(s.equals("reqReset")) {
                mBtnNewGame.setText("新規");
                mBtnNewGame.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
                
                mBtnLevelSet.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
                mBtnLevelSet.setEnabled(true);
				return;
            }
            if(s.equals("reqNewGame")) {
                mBtnNewGame.setText("やり直し");
                mBtnNewGame.setBackgroundColor(getResources().getColor(R.color.btn_bg_game_reset));
                return;
            }
            if(s.equals("notifyWin")) {
                subStartParticleFW();
                new Handler(Looper.myLooper()).postDelayed(new Runnable() { public void run() {
                    mViewHint.startShowWin();
                }}, 4000);

                mBtnNewGame.setText("新規");
                mBtnNewGame.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));

                mBtnAnswer.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
                mBtnAnswer.setEnabled(false);

                mBtnCheck.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
                mBtnCheck.setEnabled(false);

                mBtnLevelSet.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
                mBtnLevelSet.setEnabled(true);

                mBtnHint.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
                mBtnHint.setEnabled(false);
                mViewHint.mHintSt = SdHint.ST_ALL_OFF;
                mViewHint.invalidate();
                mBtnHint.setText("ヒントON");
                return;
            }
            if(s.equals("notifyEnterGaming")) {
                mBtnAnswer.setBackgroundColor(getResources().getColor(R.color.btn_bg_game_reset));
                mBtnAnswer.setEnabled(true);

                mBtnCheck.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
                mBtnCheck.setEnabled(true);

                mBtnLevelSet.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
                mBtnLevelSet.setEnabled(false);
                return;
            }

        }};
        lb.registerReceiver(r, itf);
        Log.e(TAG, "onCreate use:" + (System.currentTimeMillis() - ml) + "ms");
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        // Trigger the initial hide() shortly after the activity has been
        // created, to briefly hint to the user that UI controls
        // are available.
        delayedHide(100);
    }

    private void toggle() {
        if (mVisible) {
            hide();
        } else {
            show();
        }
    }

    private void hide() {
        // Hide UI first
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }
        mControlsView.setVisibility(View.GONE);
        mVisible = false;

        // Schedule a runnable to remove the status and navigation bar after a delay
        mHideHandler.removeCallbacks(mShowPart2Runnable);
        mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
    }

    private void show() {
        // Show the system bar
        mRegionMain.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
        mVisible = true;

        // Schedule a runnable to display UI elements after a delay
        mHideHandler.removeCallbacks(mHidePart2Runnable);
        mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
    }

    /**
     * Schedules a call to hide() in delay milliseconds, canceling any
     * previously scheduled calls.
     */
    private void delayedHide(int delayMillis) {
        mHideHandler.removeCallbacks(mHideRunnable);
        mHideHandler.postDelayed(mHideRunnable, delayMillis);
    }
    private void doNewGame() {
        mSdGame.newGame();
        mRegionMain.mainRegionReset().invalidate();

        mBtnAnswer.setBackgroundColor(getResources().getColor(R.color.btn_bg_game_reset));
        mBtnAnswer.setEnabled(true);

        mBtnHint.setEnabled(true);
        mViewHint.mHintSt = SdHint.ST_ALL_OFF;
        mBtnHint.setText("ヒントON");
        mBtnHint.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));

        new Thread(new Runnable() { public void run() {
            mViewHint.makeWinTxtBmp();
        }}).start();
    }

    private void doOnclick_new_game() {
        String s = mBtnNewGame.getText().toString();
        if(s.equals("新規")) {
            doNewGame();
            return;
        }
        if(s.equals("やり直し")) {
            Context upVal = this;
            new AlertDialog.Builder(this).setTitle("入力した" + mSdGame.getUserSetCnt() + "項目を全部リセットしますか？" )
                .setPositiveButton("確認", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {
                    mSdGame.gameReset();
                    mRegionMain.mainRegionReset().invalidate();
                }}).setNegativeButton("いいえ", null).show();
            return;
        }
    }

    private void doOnclick_condi_answer() {
        AlertDialog.Builder ad = new AlertDialog.Builder(this).setTitle("解答を見たら、今回のゲームが続けなくなりますよ" );
        ad.setPositiveButton("良い", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {
            mSdGame.showAnswer();
            mViewHint.hintReset().invalidate();
            mRegionMain.mainRegionReset().invalidate();

            mBtnAnswer.setBackgroundColor(getResources().getColor(R.color.btn_bg_gray));
            mBtnAnswer.setEnabled(false);

            mBtnNewGame.setText("新規");
            mBtnNewGame.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));

            mBtnLevelSet.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
            mBtnLevelSet.setEnabled(true);
        }});
        ad.setNegativeButton("キャンセル", null).show();
    }

    private void doOnclick_check_err() {
        if(0 == mSdGame.doCheck()) {
            Toast.makeText(this,"Check OK.", Toast.LENGTH_SHORT).show();
            return;
        }
        mRegionMain.invalidate();
        new Handler(Looper.myLooper()).postDelayed(new Runnable() { public void run() {
            mSdGame.resetCheckErr();
            mRegionMain.invalidate();
        }}, 2 * 1000); //ms

    }

    private void subStartParticleFW() {
        mSdGame.mGameSt |= SdGame.GMST_FLAG_WIN_ANI;
        mRegionMain.invalidate();

        int fwCnt;
        if(0 == mSdGame.mGameLevel) {
            int baseCnt = mSdGame.mGameLevel * 6; // [1, 5]  => *6:[6-30]
            fwCnt = ParticleFW.rand(baseCnt + 20, baseCnt + 50); //[26, 56] ~ [50, 80]
        } else {
            fwCnt = ParticleFW.rand( 5, 80);
        }
        Log.e(TAG, "fwCnt:" + fwCnt);
        for(int i = 0; i < fwCnt; ++i) {
            int delayMs = ParticleFW.rand(0, 2000);
            new Handler(Looper.myLooper()).postDelayed(new Runnable() { public void run() {
                runOnUiThread(new Runnable() { public void run() {
                    int fromX = ParticleFW.rand(0, mDm.widthPixels);
                    int fromY = mDm.heightPixels * 3 / 4;
                    int tarX = ParticleFW.rand(100, mDm.widthPixels - 100);
                    int tarY = ParticleFW.rand(100, mViewHint.getTop() - 100);
                    mPartiFwView.startNewFW(fromX, fromY, tarX, tarY);
                }});
            }}, delayMs);
        }
        mPartiFwView.mStatus = ParticleFW.ST_PLAYING;
        mMoreRedrawCnt = 0;

        if(null == mTm) {
            //mTm.cancel();
            mTm = new Timer();
            mTask = new TimerTask() {
                public void run() {
                    runOnUiThread(new Runnable() { public void run() {
                        if(mPartiFwView.update()) {
                            mPartiFwView.invalidate();
                            return;
                        }
                        if(mMoreRedrawCnt < REDRAW_MAX) {
                            mPartiFwView.invalidate();
                            ++mMoreRedrawCnt;
                            return;
                        }
                        if(mMoreRedrawCnt == REDRAW_MAX) {
                            mSdGame.mGameSt &= ~SdGame.GMST_FLAG_WIN_ANI;
                            mRegionMain.invalidate();
                            ++mMoreRedrawCnt;
                            return;
                        }
                    }});
                }
            };
            mTm.schedule(mTask, 0, 40);
        }
    }

    private void doOnclick_btn_quit() {
        AlertDialog.Builder ad = new AlertDialog.Builder(this).setTitle("アプリを終了します？" );
        ad.setPositiveButton("はい", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {
            finish();
        }});
        ad.setNegativeButton("いいえ", null).show();
    }

    private void doOnclick_btn_diff_level() {
        AlertDialog.Builder lvlSetting = new AlertDialog.Builder(this);
        lvlSetting.setIcon(R.mipmap.ic_launcher_round);
        lvlSetting.setTitle("難易度設定");
        lvlSetting.setSingleChoiceItems(mSdGame.DIFFI_TXT, mSdGame.mGameLevel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mTmpDiffiLevel = which;
            }
        });
        lvlSetting.setPositiveButton("确定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) {
            if(mSdGame.mGameLevel != mTmpDiffiLevel) {
                mSdGame.mGameLevel = mTmpDiffiLevel;
                mSdGame.diffiLevelChanged();
                doNewGame();
                if(0 != mSdGame.mGameLevel) { //hide if not test level
                    mBtnHanabParti.setVisibility(View.GONE);
                    mBtnHanabBmps.setVisibility(View.GONE);
                    mBtnWinAni.setVisibility(View.GONE);
                    mBtnArtPix.setVisibility(View.GONE);
                    return;
                }
                mBtnHanabParti.setVisibility(View.VISIBLE);
                mBtnHanabBmps.setVisibility(View.VISIBLE);
                mBtnWinAni.setVisibility(View.VISIBLE);
                mBtnArtPix.setVisibility(View.VISIBLE);
            }
        }});
        lvlSetting.setNegativeButton("キャンセル", null).show();
    }

    private void doOnclick_btn_hint() {
        if(mBtnHint.getText().toString().equals("ヒントON")) {
            mViewHint.mHintSt = SdHint.ST_HINT_ON;
            mBtnHint.setText("ヒントOFF");
            mBtnHint.setBackgroundColor(getResources().getColor(R.color.btn_bg_hint_off));
            mViewHint.invalidate();
            mRegionMain.invalidate();
            return;
        }
        mViewHint.mHintSt = SdHint.ST_ALL_OFF;
        mBtnHint.setText("ヒントON");
        mBtnHint.setBackgroundColor(getResources().getColor(R.color.btn_bg_def));
        mRegionMain.invalidate();
        mViewHint.invalidate();
    }

    private void doOnclick_btn_hanab_parti() {
        subStartParticleFW();
    }
    private void doOnclick_btn_hanab_bmps() {
        mFirework.startAni();
    }
    private void doOnclick_btn_win_ani() {
        mViewHint.makeWinTxtBmp();
        mViewHint.startShowWin();
    }
    private void doOnclick_btn_art_pix() {
        startActivity(new Intent(this, artPixel.class));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.new_game: doOnclick_new_game(); break;
            case R.id.condi_answer: doOnclick_condi_answer(); break;
            case R.id.check_err: doOnclick_check_err(); break;
            case R.id.btn_quit: doOnclick_btn_quit(); break;
            case R.id.btn_diff_level: doOnclick_btn_diff_level(); break;
            case R.id.btn_hint: doOnclick_btn_hint(); break;
            case R.id.btn_hanab_parti: doOnclick_btn_hanab_parti(); break;
            case R.id.btn_hanab_bmps: doOnclick_btn_hanab_bmps(); break;
            case R.id.btn_win_ani: doOnclick_btn_win_ani(); break;
            case R.id.btn_art_pix: doOnclick_btn_art_pix(); break;
            default: break;
        }
    }
}